﻿using System;
using System.Text;
using u = FinPlusUtility.Utility;

namespace Messaging2
{
    public sealed class Message: IMessage
    {
        public string Topic { get; set; }
        public object Value { get; set; }
        public ValType ValueType { get; set; }
        public ActType ActionType { get; set; }
        public Exception Exception { get; set; }
        public bool RequestResendCache { get { return _requestResendCache; } set { _requestResendCache = value; } }
 
        private bool _requestResendCache = false;
        
        //construct
        public Message(Exception exception)
        {
            Exception = exception;
            Topic = "Error";
            ActionType = ActType.Unknown;
        }

        public Message(string val, string topic, ActType actionType = ActType.Unknown)
        {
            Value = val;
            Topic = topic;
            ValueType = ValType.String;
            ActionType = actionType;
        }

        public Message(double val, string topic, ActType actionType = ActType.Unknown)
        {
            Value = val;
            Topic = topic;
            ValueType = ValType.String;
            ActionType = actionType;
        }

        public Message(object[] val, string topic, ActType actionType = ActType.Unknown)
        {
            Value = val;
            Topic = topic;
            ValueType = ValType.Array1D;
            ActionType = actionType;
        }

        public Message(object[,] val, string topic, ActType actionType = ActType.Unknown)
        {
            Value = val;
            Topic = topic;
            ValueType = ValType.Array2D;
            ActionType = actionType;
        }

        public Message(string val, char delimiterInfo = '|')
        {
            try
            {
                var s = val.Split(delimiterInfo);
                Topic = s[0];
                
                if (s.Length < 5) return;

                ValueType = u.EnumParse<ValType>(s[1], ValType.String);
                RequestResendCache = bool.Parse(s[2]);
                ActionType = u.EnumParse<ActType>(s[3], ActType.Unknown);

                switch (ValueType)
                {
                    case ValType.String: Value = s[4]; break;
                    case ValType.Number: Value = double.Parse(s[4]); break;
                    case ValType.Array1D: Value = u.StringToArray1d(s[4]); break;
                    case ValType.Array2D: Value = u.StringToArray2d(s[4]); break;
                }
            }
            catch (Exception e)
            {
                Exception = e;
            }
        }

        //public
        public override string ToString()
        {
            return ToString('|');
        }

        public string ToString(char delimiterInfo = '|')
        {
            var sb = new StringBuilder();
            try
            {
                if (Value == null) return "#Error";

                //basic info like attributes in tibo a bit simple
                sb.Append(Topic);
                sb.Append(delimiterInfo);
                sb.Append(ValueType.ToString());
                sb.Append(delimiterInfo);
                sb.Append(RequestResendCache.ToString());
                sb.Append(delimiterInfo);
                sb.Append(ActionType.ToString());
                sb.Append(delimiterInfo);

                switch (ValueType)
                {
                    case ValType.String: sb.Append(Value.ToString()); break;
                    case ValType.Number: sb.Append(Value.ToString()); break;
                    case ValType.Array1D: sb.Append(u.StringFromArray1d((object[])Value)); break;
                    case ValType.Array2D: sb.Append(u.StringFromArray2d((object[,])Value)); break;
                }
                return sb.ToString();
            }
            catch (Exception e)
            {
                return e.ToString();
            }
        }
    }
}
